﻿using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;

namespace ZYCommon
{
   

    public class PropertyList : UserControl
    {
        private int intItemHeight = 0x17;
        private int intLabelWidth = 15;
        private int intUpdateLevel = 0;
        private Button myButton;
        private ArrayList myItems = new ArrayList();
        private NumericUpDown myNumber;
        private PropertyItem mySelectedItem = null;
        private TextBox myTextBox;

        public PropertyList()
        {
            this.AutoScroll = true;
            this.BackColor = SystemColors.Control;
            this.myTextBox = new TextBox();
            this.myTextBox.Visible = false;
            base.Controls.Add(this.myTextBox);
            EventHandler handler = new EventHandler(this.myTextBox_LostFocus);
            this.myTextBox.LostFocus += handler;
            this.myTextBox.KeyDown += new KeyEventHandler(this.myTextBox_KeyDown);
            this.myNumber = new NumericUpDown();
            this.myNumber.Visible = false;
            base.Controls.Add(this.myNumber);
            this.myNumber.ValueChanged += new EventHandler(this.myNumber_ValueChanged);
            this.myButton = new Button();
            this.myButton.Visible = false;
            this.myButton.Size = new Size(20, 20);
            this.myButton.Text = "...";
            base.Controls.Add(this.myButton);
            this.myButton.Click += new EventHandler(this.myButton_Click);
        }

        public void BeginUpdate()
        {
            this.intUpdateLevel++;
        }

        public void EndUpdate()
        {
            this.intUpdateLevel--;
            if (this.intUpdateLevel <= 0)
            {
                this.intUpdateLevel = 0;
                this.UpdateView();
            }
        }

        private Rectangle GetItemViewBounds(PropertyItem myItem)
        {
            return new Rectangle(0, (this.myItems.IndexOf(myItem) * this.intItemHeight) + base.AutoScrollPosition.Y, base.ClientSize.Width, this.intItemHeight);
        }

        private Rectangle GetValueViewBounds(PropertyItem myItem)
        {
            return new Rectangle(this.intLabelWidth + 2, ((this.myItems.IndexOf(myItem) * this.intItemHeight) + base.AutoScrollPosition.Y) + 1, (base.ClientSize.Width - this.intLabelWidth) - 3, this.intItemHeight - 2);
        }

        public PropertyItem HitTest(int x, int y)
        {
            y -= base.AutoScrollPosition.Y;
            int num = (int) Math.Floor((double) (y / this.intItemHeight));
            if ((num >= 0) && (num < this.myItems.Count))
            {
                return (PropertyItem) this.myItems[num];
            }
            return null;
        }

        protected override bool IsInputKey(Keys keyData)
        {
            return true;
        }

        private void myButton_Click(object sender, EventArgs e)
        {
            PropertyItem tag = this.myButton.Tag as PropertyItem;
            if ((tag != null) && (tag.Value is Color))
            {
                using (ColorDialog dialog = new ColorDialog())
                {
                    dialog.Color = (Color) tag.Value;
                    dialog.AllowFullOpen = true;
                    if (dialog.ShowDialog(this) == DialogResult.OK)
                    {
                        tag.Value = dialog.Color;
                        this.RefreshItem(tag);
                    }
                }
            }
        }

        private void myNumber_ValueChanged(object sender, EventArgs e)
        {
            if (this.myNumber.Visible)
            {
                PropertyItem tag = this.myNumber.Tag as PropertyItem;
                if (tag != null)
                {
                    tag.Value = (int) this.myNumber.Value;
                }
            }
        }

        private void myTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                this.myTextBox_LostFocus(sender, null);
                this.SelectedIndex++;
            }
        }

        private void myTextBox_LostFocus(object sender, EventArgs e)
        {
            if ((sender == this.myNumber) && this.myNumber.Visible)
            {
                this.myNumber.Visible = false;
                PropertyItem tag = this.myNumber.Tag as PropertyItem;
                if (tag != null)
                {
                    tag.Value = (int) this.myNumber.Value;
                    this.RefreshItem(tag);
                }
            }
            if ((sender == this.myTextBox) && this.myTextBox.Visible)
            {
                this.myTextBox.Visible = false;
                PropertyItem myItem = this.myTextBox.Tag as PropertyItem;
                if (myItem != null)
                {
                    try
                    {
                        if (myItem.Value is string)
                        {
                            myItem.Value = this.myTextBox.Text;
                        }
                        else if (myItem.Value is int)
                        {
                            myItem.Value = Convert.ToInt32(this.myTextBox.Text);
                        }
                        else if (myItem.Value is float)
                        {
                            myItem.Value = Convert.ToSingle(this.myTextBox.Text);
                        }
                        else if (myItem.Value is double)
                        {
                            myItem.Value = Convert.ToDouble(this.myTextBox.Text);
                        }
                    }
                    catch
                    {
                    }
                    this.RefreshItem(myItem);
                }
            }
        }

        public PropertyItem NewItem(string strName, string strText, object objValue)
        {
            PropertyItem item = new PropertyItem();
            this.myItems.Add(item);
            item.Name = strName;
            item.Label = strText;
            item.Value = objValue;
            return item;
        }

        protected override void OnClick(EventArgs e)
        {
            if (this.myTextBox.Visible)
            {
                this.myTextBox_LostFocus(this.myTextBox, null);
            }
            Point pt = base.PointToClient(Control.MousePosition);
            PropertyItem item = this.HitTest(pt.X, pt.Y);
            if (item != null)
            {
                if (item != this.mySelectedItem)
                {
                    this.SelectedItem = item;
                }
                if (this.GetValueViewBounds(this.mySelectedItem).Contains(pt))
                {
                    if (this.mySelectedItem.Value is bool)
                    {
                        this.mySelectedItem.Value = !((bool) this.mySelectedItem.Value);
                    }
                    else
                    {
                        if (this.myTextBox.Visible)
                        {
                            this.myTextBox.Focus();
                            this.myTextBox.SelectAll();
                        }
                        if (this.myNumber.Visible)
                        {
                            this.myNumber.Focus();
                        }
                    }
                }
            }
            this.RefreshItem(this.mySelectedItem);
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                    if (this.mySelectedItem != null)
                    {
                        this.SelectedIndex--;
                        break;
                    }
                    this.SelectedIndex = 0;
                    break;

                case Keys.Down:
                    if (this.mySelectedItem != null)
                    {
                        this.SelectedIndex++;
                        break;
                    }
                    this.SelectedIndex = 0;
                    break;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            this.intLabelWidth = 15;
            foreach (PropertyItem item in this.myItems)
            {
                SizeF ef = graphics.MeasureString(item.Label, this.Font);
                if (this.intLabelWidth < (ef.Width + 2f))
                {
                    this.intLabelWidth = ((int) ef.Width) + 2;
                } 
            }
            if (this.intLabelWidth < ((base.ClientSize.Width - 3) * 0.4))
            {
                this.intLabelWidth = (int) ((base.ClientSize.Width - 3) * 0.4);
            }
            Rectangle rect = new Rectangle(0, base.AutoScrollPosition.Y, base.ClientSize.Width, this.intItemHeight);
            Rectangle clipRectangle = e.ClipRectangle;
            graphics.DrawLine(SystemPens.WindowText, this.intLabelWidth, clipRectangle.Top, this.intLabelWidth, clipRectangle.Bottom);
            foreach (PropertyItem item2 in this.myItems)
            {
                if (rect.IntersectsWith(clipRectangle))
                {
                    graphics.FillRectangle((item2 == this.mySelectedItem) ? SystemBrushes.Highlight : SystemBrushes.Control, new Rectangle(rect.Left, rect.Top, this.intLabelWidth, rect.Height));
                    graphics.DrawRectangle(SystemPens.ControlDarkDark, rect);
                    graphics.DrawString(item2.Label, this.Font, (item2 == this.mySelectedItem) ? SystemBrushes.HighlightText : SystemBrushes.WindowText, new RectangleF((float) (rect.Left + 3), (float) (rect.Top + ((int) ((rect.Height - this.Font.GetHeight()) / 2f))), (float) this.intLabelWidth, (float) rect.Height));
                    Rectangle rectangle3 = new Rectangle(this.intLabelWidth + 1, rect.Top, (base.ClientSize.Width - this.intLabelWidth) + 1, this.intItemHeight);
                    RectangleF ef2 = new RectangleF((float) rectangle3.Left, (float) rectangle3.Top, (float) rectangle3.Width, (float) rectangle3.Height);
                    Rectangle rectangle = new Rectangle(rectangle3.Left + 2, rectangle3.Top + ((rectangle3.Height - 0x10) / 2), 0x10, 0x10);
                    Rectangle layoutRectangle = new Rectangle(rectangle3.Left + 2, rect.Top + ((int) ((rect.Height - this.Font.GetHeight()) / 2f)), base.ClientSize.Width - rectangle3.Left, (int) this.Font.GetHeight());
                    if (item2.Value is bool)
                    {
                        ButtonState flat = ButtonState.Flat;
                        if ((bool) item2.Value)
                        {
                            flat |= ButtonState.Checked;
                        }
                        ControlPaint.DrawCheckBox(graphics, rectangle, flat);
                    }
                    else if (item2.Value is Color)
                    {
                        using (SolidBrush brush = new SolidBrush((Color) item2.Value))
                        {
                            graphics.FillRectangle(brush, rectangle);
                        }
                        graphics.DrawRectangle(SystemPens.WindowText, rectangle);
                        Color color = (Color) item2.Value;
                        string s = "#" + Convert.ToInt32((int) (color.ToArgb() & 0xffffff)).ToString("X6");
                        layoutRectangle.X += 0x12;
                        graphics.DrawString(s, this.Font, SystemBrushes.WindowText, layoutRectangle);
                    }
                    else
                    {
                        graphics.DrawString(item2.Value.ToString(), this.Font, SystemBrushes.WindowText, layoutRectangle);
                    }
                }
                else if (rect.Top > clipRectangle.Bottom)
                {
                    break;
                }
                rect.Y += this.intItemHeight;
            }
        }

        public void RefreshItem(PropertyItem myItem)
        {
            base.Invalidate(new Rectangle(0, ((this.myItems.IndexOf(myItem) * this.intItemHeight) - 3) + base.AutoScrollPosition.Y, base.ClientSize.Width, this.intItemHeight + 6));
        }

        public void UpdateView()
        {
            base.AutoScrollMinSize = new Size(0, this.myItems.Count * this.intItemHeight);
            this.Refresh();
        }

        protected override System.Windows.Forms.CreateParams CreateParams
        {
            get
            {
                System.Windows.Forms.CreateParams createParams = base.CreateParams;
                createParams.ExStyle |= 0x200;
                return createParams;
            }
        }

        public int ItemHeight
        {
            get
            {
                return this.intItemHeight;
            }
            set
            {
                this.intItemHeight = value;
            }
        }

        public ArrayList Items
        {
            get
            {
                return this.myItems;
            }
            set
            {
                this.myItems = value;
            }
        }

        public int SelectedIndex
        {
            get
            {
                return this.myItems.IndexOf(this.mySelectedItem);
            }
            set
            {
                if ((value >= 0) && (value < this.myItems.Count))
                {
                    this.SelectedItem = (PropertyItem) this.myItems[value];
                }
            }
        }

        public PropertyItem SelectedItem
        {
            get
            {
                return this.mySelectedItem;
            }
            set
            {
                if (this.mySelectedItem != value)
                {
                    PropertyItem mySelectedItem = this.mySelectedItem;
                    if (mySelectedItem != null)
                    {
                        this.RefreshItem(mySelectedItem);
                    }
                    this.mySelectedItem = value;
                    int num = (this.myItems.IndexOf(this.mySelectedItem) * this.intItemHeight) + base.AutoScrollPosition.Y;
                    if (num < 0)
                    {
                        base.AutoScrollPosition = new Point(0, num - base.AutoScrollPosition.Y);
                    }
                    else if ((num + this.intItemHeight) > base.ClientSize.Height)
                    {
                        base.AutoScrollPosition = new Point(0, ((num + this.intItemHeight) - base.ClientSize.Height) - base.AutoScrollPosition.Y);
                    }
                    this.RefreshItem(this.mySelectedItem);
                    if (this.myTextBox.Visible)
                    {
                        this.myTextBox_LostFocus(this.myTextBox, null);
                    }
                    if (this.myNumber.Visible)
                    {
                        this.myTextBox_LostFocus(this.myNumber, null);
                    }
                    if (this.myButton.Visible)
                    {
                        this.myButton.Visible = false;
                    }
                    Rectangle valueViewBounds = this.GetValueViewBounds(this.mySelectedItem);
                    if (!(this.mySelectedItem.Value is bool))
                    {
                        if (this.mySelectedItem.Value is Color)
                        {
                            this.myButton.Location = new Point((valueViewBounds.Right - this.myButton.Width) - 1, valueViewBounds.Top + ((valueViewBounds.Height - this.myButton.Height) / 2));
                            this.myButton.Tag = this.mySelectedItem;
                            this.myButton.Show();
                        }
                        else if (((this.mySelectedItem.Value is int) || (this.mySelectedItem.Value is long)) || (((this.mySelectedItem.Value is float) || (this.mySelectedItem.Value is double)) || (this.mySelectedItem.Value is decimal)))
                        {
                            this.myNumber.Bounds = valueViewBounds;
                            this.myNumber.Value = (int) this.mySelectedItem.Value;
                            this.myNumber.Tag = this.mySelectedItem;
                            this.myNumber.Show();
                        }
                        else
                        {
                            this.myTextBox.Bounds = valueViewBounds;
                            this.myTextBox.Text = this.mySelectedItem.Value.ToString();
                            this.myTextBox.Tag = this.mySelectedItem;
                            this.myTextBox.Show();
                        }
                    }
                }
            }
        }
    }
}

